package com.kun.video.ui.slider;

import com.kun.video.ui.ComponentUtil;
import com.kun.video.ui.KunComponent;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.value.ChangeListener;
import javafx.event.EventHandler;
import javafx.scene.Parent;
import javafx.scene.control.Slider;
import javafx.scene.input.MouseEvent;
import javafx.util.Duration;

/**
 * 高性能可扩展滑动条基类
 *
 * <h2>设计目标</h2>
 * 1. 性能优化：通过事件节流降低高频操作时的CPU占用<br>
 * 2. 扩展性：提供可重写的生命周期方法和事件回调<br>
 * 3. 资源管理：自动清理无效监听器，避免内存泄漏<br>
 *
 * <h2>扩展点</h2>
 * 1. {@link #onValueChanging(double)} - 值变更时的回调（可节流）<br>
 * 2. {@link #createThrottleTimeline()} - 自定义节流时间控制<br>
 *
 * <h2>生命周期</h2>
 * 构造器 -> 初始化样式/监听器 -> onSliderInitialized() -> 用户交互 -> 事件回调 -> 释放资源
 *
 * @author gzc
 */
public class KunSlider extends Slider implements KunComponent {
    private static final String CSS_CLASS = "kun-slider";
    /**
     * 事件节流默认时间
     */
    private static final int DEFAULT_THROTTLE_MS = 10;
    private static final String DEFAULT_TRACK_HEIGHT = "12px";
    private static final String DEFAULT_THUMB_SIZE = "12px";
    private static final String DEFAULT_MAIN_COLOR = "#2196F3";
    private final Timeline eventThrottle = createThrottleTimeline();
    /**
     * 是否拖拽
     */
    private final BooleanProperty isDragging = new SimpleBooleanProperty(false);

    public KunSlider() {
        this(0, 1, 0.5);
    }

    public KunSlider(double min, double max, double value) {
        super(min, max, value);
        KunComponent.super.initialize();
    }

    @Override
    public Parent getNode() {
        return this;
    }

    @Override
    public String getStyleName() {
        return CSS_CLASS;
    }

    @Override
    public void initStyleClass() {
        // 内联CSS变量定义
        String inlineCss = String.format(
                "-clean-track-height: %s;" +
                        "-clean-thumb-size: %s;" +
                        "-clean-main-color: %s;",
                DEFAULT_TRACK_HEIGHT,
                DEFAULT_THUMB_SIZE,
                DEFAULT_MAIN_COLOR
        );
        setStyle(inlineCss);
        KunComponent.super.initStyleClass();
    }

    @Override
    public void initLayout() {

    }

    @Override
    public void initStyle() {
        setSnapToTicks(false);
    }

    @Override
    public void initDimensions() {

    }

    @Override
    public void reactiveDimensions(double width, double height) {

    }

    @Override
    public void initData() {

    }

    /**
     * 存储值变化监听器
     */
    private final ChangeListener<Number> valueChangeListener = (obs, ov, nv) -> {
        if (isDragging.get() || !eventThrottle.getStatus().equals(Timeline.Status.RUNNING)) {
            eventThrottle.playFromStart();
        }
    };
    /**
     * 存储鼠标按下监听器
     */
    private final EventHandler<MouseEvent> mousePressedEventHandler = event -> isDragging.set(true);
    /**
     * 存储鼠标释放监听器
     */
    private final EventHandler<MouseEvent> mouseReleasedEventHandler = event -> isDragging.set(false);

    @Override
    public void initListeners() {
        ComponentUtil.weakChangeListener(valueProperty(), valueChangeListener);
        ComponentUtil.weakActionEventHandler(this, MouseEvent.MOUSE_PRESSED, mousePressedEventHandler);
        ComponentUtil.weakActionEventHandler(this, MouseEvent.MOUSE_RELEASED, mouseReleasedEventHandler);
    }

    @Override
    public void dispose() {
        // 停止时间线
        eventThrottle.stop();
        ComponentUtil.removeWeakListener(valueProperty(), valueChangeListener);
        ComponentUtil.removeWeakListener(this, MouseEvent.MOUSE_PRESSED, mousePressedEventHandler);
        ComponentUtil.removeWeakListener(this, MouseEvent.MOUSE_RELEASED, mouseReleasedEventHandler);
        // 清理属性
        getProperties().clear();
    }

    /**
     * 带节流的值变化回调（子类需重写此方法实现业务逻辑）
     *
     * @param newValue 当前滑块值（已节流处理）
     */
    protected void onValueChanging(double newValue) {
        // 默认空实现
    }

    /**
     * 创建事件节流时间线（子类可重写以调整节流时间）
     *
     * @return 节流时间线实例
     */
    protected Timeline createThrottleTimeline() {
        return new Timeline(
                new KeyFrame(Duration.millis(DEFAULT_THROTTLE_MS), e -> {
                    onValueChanging(getValue());
                    eventThrottle.stop();
                })
        );
    }

}